/*
 * Copyright 2011-2020 www.youjiang114.com
 *
 * All right reserved.
 */
package com.holylin.learning.java.language.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author holylin
 * @since 2012-3-10
 */

interface Interface {
	void doSomething();

	void somethingElse(String arg);
}

class RealObject implements Interface {
	public void doSomething() {
		System.out.println("doSomething");
	}

	public void somethingElse(String arg) {
		System.out.println("somethingElse " + arg);
	}
}

class DynamicProxyHandler implements InvocationHandler {
	private Object proxied;

	public DynamicProxyHandler(Object proxied) {
		this.proxied = proxied;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("**** proxy: " + proxy.getClass() + ", method: "
				+ method + ", args: " + args);
		if (args != null)
			for (Object arg : args)
				System.out.println("  " + arg);
		return method.invoke(proxied, args);
	}
}

class SimpleDynamicProxy {
	public static void consumer(Interface iface) {
		iface.doSomething();
		iface.somethingElse("bonobo");
	}

	public static void main(String[] args) {
		RealObject real = new RealObject();
		consumer(real);
		// Insert a proxy and call again:
		Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class
				.getClassLoader(), new Class[] { Interface.class },
				new DynamicProxyHandler(real));
		consumer(proxy);
	}
} /*
 * Output: (95% match) doSomething somethingElse bonobo*** proxy: class $Proxy0,
 * method: public abstract void Interface.doSomething(), args: null doSomething
 * *** proxy: class $Proxy0, method: public abstract void
 * Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@42e816
 * bonobo somethingElse bonobo
 */// :~
